package com.orderplus.opshop.common.util;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Map;

/**
 * Created by zhouxj6112 on 2018/12/12.
 */
public class JSONUitl {

	private static ObjectMapper objectMapper = new ObjectMapper();

	static { // 全部字段序列化
		//对象的所有字段全部列入
		objectMapper.setSerializationInclusion(Include.ALWAYS);
		//取消默认转换timestamps形式
		objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
		//所有的日期格式都统一为以下的样式，即yyyy-MM-dd HH:mm:ss
		objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		//忽略空Bean转json的错误
		objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		//忽略 在json字符串中存在，但是在java对象中不存在对应属性的情况。防止错误
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	}

	/**
	 * 对象转json string
	 *
	 * @param obj
	 * @return
	 */
	public static <T> String obj2String(T obj) {
		if (obj == null) {
			return null;
		}
		try {
			return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 有格式的
	 *
	 * @param obj
	 * @return
	 */
	public static <T> String obj2StringPretty(T obj) {
		if (obj == null) {
			return null;
		}
		try {
			return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 字符串转对象
	 *
	 * @param str
	 * @param clazz
	 * @return
	 */
	public static <T> T string2Obj(String str, Class<T> clazz) {
		if (StringUtils.isEmpty(str) || clazz == null) {
			return null;
		}

		try {
			return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 字段符转List之类的集合
	 *
	 * @param str
	 * @param typeReference
	 * @return
	 */
	public static <T> T string2Obj(String str, TypeReference typeReference) {
		if (StringUtils.isEmpty(str) || typeReference == null) {
			return null;
		}
		try {
			return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 差不多同上
	 *
	 * @param str
	 * @param collectionClass
	 * @param elementClasses
	 * @return
	 */
	public static <T> T string2Obj(String str, Class<?> collectionClass, Class<?>... elementClasses) {
		JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
		try {
			return objectMapper.readValue(str, javaType);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * map转object
	 *
	 * @param map
	 * @param beanClass
	 * @return
	 * @throws Exception
	 */
	public static Object mapToObject(Map<String, Object> map, Class<?> beanClass) throws Exception {
		if (map == null) {
			return null;
		}
		Object obj = beanClass.newInstance();

		BeanUtils.populate(obj, map);

		return obj;
	}

	/**
	 * object转map
	 *
	 * @param object
	 * @return
	 * @throws Exception
	 */
	public static Map objectToMap(Object object) {
		ObjectMapper objectMapper = new ObjectMapper();
		Map<?, ?> mappedObject = null;
		try {
			mappedObject = objectMapper.convertValue(object, Map.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mappedObject;
	}

}
